/*
 * @Author: WuFeng <763467339@qq.com>
 * @Date: 2024-11-08 21:11:00
 * @LastEditTime: 2024-11-08 21:56:30
 * @LastEditors: WuFeng <763467339@qq.com>
 * @Description: 
 * @FilePath: \markdown-magic\src\pages\NumberTools\service\index.js
 * @Copyright 版权声明
 */

//  数字转中文
export const numberToChinese = (num) => {
  if (isNaN(num)) {
    return '';
  }

  const chineseNums = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
  const chineseUnits = ['', '十', '百', '千'];
  const chineseBigUnits = ['', '万', '亿', '兆'];
  const chineseDecimalUnits = ['角', '分'];

  // 分离整数和小数部分
  const integerPart = Math.floor(num);
  const decimalPart = Math.round((num - integerPart) * 100);

  // 整数部分转换
  const digits = integerPart.toString().split('').reverse();
  let integerResult = '';
  let zeroCount = 0;

  for (let i = 0; i < digits.length; i++) {
    const digit = parseInt(digits[i], 10);
    const unitIndex = i % 4;
    const bigUnitIndex = Math.floor(i / 4);

    if (digit === 0) {
      zeroCount++;
    } else {
      if (zeroCount > 0) {
        integerResult = chineseNums[0] + integerResult;
      }
      zeroCount = 0;
      integerResult = chineseNums[digit] + chineseUnits[unitIndex] + integerResult;
    }

    if (unitIndex === 0 && bigUnitIndex > 0) {
      integerResult = chineseBigUnits[bigUnitIndex] + integerResult;
    }
  }

  // 去掉末尾的'零'
  integerResult = integerResult.replace(/零+$/, '');

  // 去掉连续的'零'
  integerResult = integerResult.replace(/零+/g, '零');

  // 小数部分转换
  const decimalDigits = decimalPart.toString().split('');
  let decimalResult = '';

  for (let i = 0; i < decimalDigits.length; i++) {
    const digit = parseInt(decimalDigits[i], 10);
    if (digit !== 0) {
      decimalResult += chineseNums[digit] + chineseDecimalUnits[i];
    }
  }

  // 合并整数和小数部分
  let finalResult = integerResult;
  if (decimalResult) {
    finalResult += '元' + decimalResult;
  } else {
    finalResult += '元整';
  }

  return finalResult;
}

//  数字转中文大写
export const numberToChineseCapital = (num) => {
  if (isNaN(num)) {
    return '';
  }

  const chineseNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
  const chineseUnits = ['', '拾', '佰', '仟'];
  const chineseBigUnits = ['', '万', '亿', '兆'];
  const chineseDecimalUnits = ['角', '分'];

  // 分离整数和小数部分
  const integerPart = Math.floor(num);
  const decimalPart = Math.round((num - integerPart) * 100);

  // 整数部分转换
  const digits = integerPart.toString().split('').reverse();
  let integerResult = '';
  let zeroCount = 0;

  for (let i = 0; i < digits.length; i++) {
    const digit = parseInt(digits[i], 10);
    const unitIndex = i % 4;
    const bigUnitIndex = Math.floor(i / 4);

    if (digit === 0) {
      zeroCount++;
    } else {
      if (zeroCount > 0) {
        integerResult = chineseNums[0] + integerResult;
      }
      zeroCount = 0;
      integerResult = chineseNums[digit] + chineseUnits[unitIndex] + integerResult;
    }

    if (unitIndex === 0 && bigUnitIndex > 0) {
      integerResult = chineseBigUnits[bigUnitIndex] + integerResult;
    }
  }

  // 去掉末尾的'零'
  integerResult = integerResult.replace(/零+$/, '');

  // 去掉连续的'零'
  integerResult = integerResult.replace(/零+/g, '零');

  // 小数部分转换
  const decimalDigits = decimalPart.toString().split('');
  let decimalResult = '';

  for (let i = 0; i < decimalDigits.length; i++) {
    const digit = parseInt(decimalDigits[i], 10);
    if (digit !== 0) {
      decimalResult += chineseNums[digit] + chineseDecimalUnits[i];
    }
  }

  // 合并整数和小数部分
  let finalResult = integerResult;
  if (decimalResult) {
    finalResult += '元' + decimalResult;
  } else {
    finalResult += '元整';
  }

  return finalResult;
}

// 数字转英文
export const numberToEnglish = (num) => {
  if (isNaN(num)) {
    return '';
  }

  const units = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine'];
  const teens = ['Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'];
  const tens = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety'];
  const thousands = ['', 'Thousand', 'Million', 'Billion', 'Trillion'];

  function convertHundreds(n) {
    let result = '';
    if (n >= 100) {
      result += units[Math.floor(n / 100)] + ' Hundred ';
      n %= 100;
    }
    if (n >= 20) {
      result += tens[Math.floor(n / 10)] + ' ';
      n %= 10;
    }
    if (n >= 10) {
      result += teens[n - 10] + ' ';
      n = 0;
    }
    if (n > 0) {
      result += units[n] + ' ';
    }
    return result.trim();
  }

  // 分离整数和小数部分
  let integerPart = Math.floor(num);
  const decimalPart = Math.round((num - integerPart) * 100);

  // 整数部分转换
  let integerResult = '';
  if (integerPart === 0) {
    integerResult = 'Zero';
  } else {
    let i = 0;
    while (integerPart > 0) {
      if (integerPart % 1000 !== 0) {
        integerResult = convertHundreds(integerPart % 1000) + ' ' + thousands[i] + ' ' + integerResult;
      }
      integerPart = Math.floor(integerPart / 1000);
      i++;
    }
  }

  // 小数部分转换
  let decimalResult = '';
  if (decimalPart > 0) {
    if (decimalPart < 10) {
      decimalResult = units[decimalPart] + ' Cents';
    } else if (decimalPart < 20) {
      decimalResult = teens[decimalPart - 10] + ' Cents';
    } else {
      const tensDigit = Math.floor(decimalPart / 10);
      const unitsDigit = decimalPart % 10;
      decimalResult = tens[tensDigit] + (unitsDigit > 0 ? ' ' + units[unitsDigit] : '') + ' Cents';
    }
  }

  // 合并整数和小数部分
  let finalResult = integerResult;
  if (decimalResult) {
    finalResult += ' and ' + decimalResult;
  } else {
    finalResult += ' Dollars';
  }

  return finalResult.trim();
}

// 英文转数字
export const englishToNumber = (english) => {
  const units = { One: 1, Two: 2, Three: 3, Four: 4, Five: 5, Six: 6, Seven: 7, Eight: 8, Nine: 9 };
  const teens = { Ten: 10, Eleven: 11, Twelve: 12, Thirteen: 13, Fourteen: 14, Fifteen: 15, Sixteen: 16, Seventeen: 17, Eighteen: 18, Nineteen: 19 };
  const tens = { Twenty: 20, Thirty: 30, Forty: 40, Fifty: 50, Sixty: 60, Seventy: 70, Eighty: 80, Ninety: 90 };
  const thousands = { Thousand: 1000, Million: 1000000, Billion: 1000000000, Trillion: 1000000000000 };

  const words = english.split(' ');
  let result = 0;
  let current = 0;
  let currentMultiplier = 1;

  for (let i = 0; i < words.length; i++) {
    const word = words[i];

    if (word in units) {
      current += units[word];
    } else if (word in teens) {
      current += teens[word];
    } else if (word in tens) {
      current += tens[word];
    } else if (word === 'Hundred') {
      current *= 100;
    } else if (word in thousands) {
      current *= thousands[word];
      result += current;
      current = 0;
      currentMultiplier = 1;
    } else if (word === 'and') {
      continue; // Skip 'and'
    } else if (word === 'Dollars') {
      result += current;
      current = 0;
    } else if (word === 'Cents') {
      result += current / 100;
      break;
    } else {
      throw new Error(`Unknown word: ${word}`);
    }
  }

  result += current;

  return result;
}

// 十进制转罗马数字
export const decimalToRoman = (num) => {
  if (typeof num !== 'number' || num <= 0 || num >= 4000) {
    throw new Error('Input must be a positive number less than 4000');
  }

  const romanMap = [
    [1000, 'M'], [900, 'CM'], [500, 'D'], [400, 'CD'],
    [100, 'C'], [90, 'XC'], [50, 'L'], [40, 'XL'],
    [10, 'X'], [9, 'IX'], [5, 'V'], [4, 'IV'], [1, 'I']
  ];

  let roman = '';

  for (let i = 0; i < romanMap.length; i++) {
    while (num >= romanMap[i][0]) {
      roman += romanMap[i][1];
      num -= romanMap[i][0];
    }
  }

  return roman;
}

// 罗马数字转十进制
export const romanToDecimal = (roman) => {
  if (typeof roman !== 'string' || roman.length === 0) {
    throw new Error('Input must be a non-empty string');
  }

  const romanMap = {
    'I': 1,
    'V': 5,
    'X': 10,
    'L': 50,
    'C': 100,
    'D': 500,
    'M': 1000
  };

  let decimal = 0;
  let prevValue = 0;

  for (let i = roman.length - 1; i >= 0; i--) {
    const currentValue = romanMap[roman[i]];

    if (currentValue === undefined) {
      throw new Error('Invalid Roman numeral character');
    }

    if (currentValue < prevValue) {
      decimal -= currentValue;
    } else {
      decimal += currentValue;
    }

    prevValue = currentValue;
  }

  return decimal;
}

// 二进制转十进制
export const binaryToDecimal = (binary) => {
  if (typeof binary !== 'string' || !/^[01]+$/.test(binary)) {
    throw new Error('Input must be a valid binary string');
  }

  let decimal = 0;
  const length = binary.length;

  for (let i = 0; i < length; i++) {
    if (binary[i] === '1') {
      decimal += Math.pow(2, length - i - 1);
    }
  }

  return decimal;
}

// 二进制转十六进制
export const binaryToHex = (binary) => {
  if (typeof binary !== 'string' || !/^[01]+$/.test(binary)) {
    throw new Error('Input must be a valid binary string');
  }

  // 将二进制字符串转换为十进制数
  const decimal = binaryToDecimal(binary);

  // 将十进制数转换为十六进制字符串
  const hex = decimal.toString(16).toUpperCase();

  return hex;
}